package cn.siat.gene.service.impl;

import cn.siat.common.core.exception.ServiceException;
import cn.siat.common.security.utils.SecurityUtils;
import cn.siat.gene.domain.*;
import cn.siat.gene.domain.dto.GenomeDataDto;
import cn.siat.gene.domain.dto.GenomeDataQueryParam;
import cn.siat.gene.domain.vo.GenomeDataVO;
import cn.siat.gene.mapper.GenomeDataMapper;
import cn.siat.gene.mapper.MinioFileMapper;
import cn.siat.gene.mapper.ProgrammeFileMinioMapper;
import cn.siat.gene.service.IGenomeDataService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class GenomeDataServiceImpl extends ServiceImpl<GenomeDataMapper, GenomeData> implements IGenomeDataService {

    @Autowired
    private GenomeDataMapper genomeDataMapper;
    @Resource
    private  MinioFileMapper minioFileMapper;
    @Autowired
    private ProgrammeFileMinioMapper programmeFileMinioMapper;
    @Override
    public List<GenomeDataVO> queryPageList(GenomeDataQueryParam queryParams) {
        String genomeDataName = queryParams.getName();
        String userId = SecurityUtils.getUserId();
        queryParams.setCreateBy(userId);
        if(StringUtils.hasLength(genomeDataName)){
            queryParams.setName(genomeDataName.trim());
        }
        return  genomeDataMapper.queryProgrammeList(queryParams);
    }

    @Override
    @Transactional
    public int deleteGenomeDataById(GenomeData genomeData) {
        if(genomeDataMapper.selectById(genomeData.getId())==null){
            throw new ServiceException("删除基因组数据不存在！");
        }

        return genomeDataMapper.deleteById(genomeData);
    }

    @Override
    public Boolean checkName(String genomeDataName, String id) {
        QueryWrapper<GenomeData> wrapper = new QueryWrapper<GenomeData>()
                .eq("name", genomeDataName)
                .eq("create_by", SecurityUtils.getUserId());
        //编辑弹窗不校验本身
        if(id!=null){
            wrapper.ne("id", id);
        }
        Long count = genomeDataMapper.selectCount(wrapper);
        if(count == null || count == 0L){
            return  false;
        }
        return true;
    }

    @Override
    public String insertGenomeDataDto(GenomeDataDto genomeDataDto) {
        List<Map<String,String>> md5s = genomeDataDto.getMd5s();
        String genomeDataName = genomeDataDto.getName();
        String type = genomeDataDto.getType();
        Integer size = genomeDataDto.getSize();
        Integer count = genomeDataDto.getCount();
        if(md5s==null){
            throw new ServiceException("请上传文件");
        }
        String mdsStr= "";
        for (int i = 0; i < md5s.size(); i++) {
            mdsStr+=md5s.get(i).get("md5")+",";
        }
        //去掉最后的逗号
        if(mdsStr.length()>0){
            mdsStr=mdsStr.substring(0,mdsStr.length()-1);
        }
        if (genomeDataName==null||genomeDataName.length()==0){
            throw new ServiceException("请填写基因组数据名称");
        }
        if(!"1".equals(type)&&!"2".equals(type)&&!"3".equals(type)&&!"4".equals(type)){
            throw new ServiceException("上传文件类型组合错误");
        }
        if(size<1||count<1){
            throw new ServiceException("请上传文件");
        }
        GenomeData genomeData = new GenomeData();
        genomeData.setName(genomeDataName);
        genomeData.setCount(count);
        genomeData.setType(type);
        genomeData.setCreateTime(new Date());
        genomeData.setUpdateTime(new Date());
        // 上传中状态
        genomeData.setStatus(1);
        genomeData.setSize(size);
        genomeData.setMinioFileMd5Str(mdsStr);
        genomeData.setCreateBy(SecurityUtils.getUserId());
        genomeDataMapper.insert(genomeData);
        QueryWrapper<GenomeData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name",genomeDataName );
        String genomeDataId = genomeDataMapper.selectOne(queryWrapper).getId();

        for (int i = 0; i < md5s.size(); i++) {
            programmeFileMinioMapper.insert(
                    new ProgrammeFlieMinio().setProgrammeFileId(genomeDataId)
                            .setMinioMd5(md5s.get(i).get("md5"))
                            .setFileName(md5s.get(i).get("fileName"))
            );
        }

        return genomeDataId;

    }

    @Override
    public List<String> queryFileList(String minioIdStr) {
        //minio的文件名前面拼接了字符串，以“-”分隔
        String separator = "-";
        if(minioIdStr==null||minioIdStr.length()==0){
            throw new ServiceException("该条基因组数据没有文件");
        }
        String[] minioIds = minioIdStr.split(",");
        List<String> minioNames=new ArrayList<>();
        for (String minioId : minioIds) {
            MinioFile minioFile = minioFileMapper.selectById(minioId);
            if (minioFile==null){
                throw new ServiceException("该条基因组数据中文件已被清空，请重新上传");
            }
            //找到第一个“-”index
            int indexOfSeparator=minioFile.getFileName().indexOf(separator);
            //只取file_name列的后半部分
            minioNames.add(minioFile.getFileName().substring(indexOfSeparator + separator.length()));
        }
        return minioNames;
    }

    @Override
    public int updateGenomeData(GenomeDataDto genomeDataDto) {
        String name = genomeDataDto.getName();
        String id = genomeDataDto.getId();
        String type = genomeDataDto.getType();
        Integer count = genomeDataDto.getCount();
        List<Map<String, String>> md5s = genomeDataDto.getMd5s();
        Integer size = genomeDataDto.getSize();

        if (name==null||name.length()==0){
            throw new ServiceException("基因组数据名称不可为空");
        }
        if(name.length()<2||name.length()>50){
            throw new ServiceException("基因组数据名称不合法，请重新输入");
        }
        if(id==null||id.length()==0){
            throw new ServiceException("修改id不可为空");
        }

        GenomeData genomeData = genomeDataMapper.selectById(id);
        if (genomeData==null){
            throw new ServiceException("修改失败，基因组数据不存在");
        }
        genomeData.setName(name);
        genomeData.setUpdateTime(new Date());
        //可能只修改了名称，传md5了才验证其他属性
        if (md5s!=null){
            if(!"1".equals(type)&&!"2".equals(type)&&!"3".equals(type)&&!"4".equals(type)){
                throw new ServiceException("上传文件类型组合错误");
            }
            if(size<1||count<1){
                throw new ServiceException("请上传文件");
            }
            String mdsStr= "";
            for (int i = 0; i < md5s.size(); i++) {
                mdsStr+=md5s.get(i).get("md5")+",";
            }
            // 上传中状态
            genomeData.setStatus(1);
            genomeData.setSize(size);
            genomeData.setCount(count);
            genomeData.setType(type);
            genomeData.setMinioFileMd5Str(mdsStr);
        }

        return genomeDataMapper.updateById(genomeData);
    }

    @Override
    public int updateGenomeDataStatus(Map<String,String> map) {
        String id = map.get("id");
        String s = map.get("status");
        Integer status = Integer.valueOf(s);
        if(id==null||id.length()==0){
            throw new ServiceException("id不能为空");
        }
        if(status==null|| (status!=1&&status!=2&&status!=3)){
            throw new ServiceException("请输入正确的状态");
        }
        GenomeData genomeData = genomeDataMapper.selectById(id);
        genomeData.setStatus(status);
        return genomeDataMapper.updateById(genomeData);
    }

    @Override
    public Long[] queryMinioFileIds(String minioFileMd5Str) {
        if(!StringUtils.hasLength(minioFileMd5Str)){
            throw new ServiceException("该条基因组数据没有文件");
        }
        String[] minioIds = minioFileMd5Str.split(",");
        List<Long> ids = new ArrayList<>();
        for (String minioId : minioIds) {
            MinioFile minioFile = minioFileMapper.getByMd5(minioId);
            if (minioFile == null || minioFile.getIsComplete() == 0) {
                throw new ServiceException("该条基因组数据中文件已被清空，请重新上传");
            }
            ids.add(minioFile.getId());
        }
        return ids.toArray(new Long[ids.size()]);
    }

}
